package cn.cdutetc.library.service;

import cn.cdutetc.library.entity.pojo.SystemLog;
import cn.cdutetc.library.entity.pojo.User;
import cn.cdutetc.library.mapper.SystemLogMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import jakarta.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 系统日志服务类
 * 负责记录登录日志、操作日志、系统运行日志等
 */
@Slf4j
@Service
public class SystemLogService {

    @Autowired
    private SystemLogMapper systemLogMapper;

    /**
     * 记录登录日志
     */
    public void recordLoginLog(String username, String realName, String ipAddress, 
                              String userAgent, boolean success, String errorMessage) {
        try {
            SystemLog systemLog = new SystemLog();
            systemLog.setLogCode("LOGIN_" + System.currentTimeMillis());
            systemLog.setUserName(realName != null ? realName : username);
            systemLog.setOperation(success ? "登录成功" : "登录失败");
            systemLog.setOperationTime(LocalDateTime.now());
            systemLog.setIpAddress(ipAddress);
            systemLog.setLogLevel(success ? "INFO" : "WARN");
            systemLog.setModule("USER_LOGIN");
            
            if (success) {
                systemLog.setRemark("用户 " + username + " 登录成功");
            } else {
                systemLog.setRemark("用户 " + username + " 登录失败: " + (errorMessage != null ? errorMessage : "用户名或密码错误"));
            }
            
            systemLogMapper.insert(systemLog);
            log.info("记录登录日志: 用户={}, 结果={}, IP={}", username, success ? "成功" : "失败", ipAddress);
        } catch (Exception e) {
            log.error("记录登录日志失败", e);
        }
    }

    /**
     * 记录用户操作日志
     */
    public void recordOperationLog(User user, String operation, String module, 
                                 String remark, HttpServletRequest request) {
        try {
            SystemLog systemLog = new SystemLog();
            systemLog.setLogCode("OP_" + System.currentTimeMillis());
            
            if (user != null) {
                systemLog.setUserId(user.getUserId());
                systemLog.setUserName(user.getRealName());
            } else {
                systemLog.setUserName("系统");
            }
            
            systemLog.setOperation(operation);
            systemLog.setOperationTime(LocalDateTime.now());
            systemLog.setLogLevel("INFO");
            systemLog.setModule(module);
            systemLog.setRemark(remark);
            
            if (request != null) {
                systemLog.setIpAddress(getClientIpAddress(request));
            } else {
                systemLog.setIpAddress("127.0.0.1");
            }
            
            systemLogMapper.insert(systemLog);
            log.debug("记录操作日志: 用户={}, 操作={}, 模块={}", 
                     user != null ? user.getRealName() : "系统", operation, module);
        } catch (Exception e) {
            log.error("记录操作日志失败", e);
        }
    }

    /**
     * 记录系统运行日志
     */
    public void recordSystemLog(String operation, String module, String level, 
                               String remark, Exception exception) {
        try {
            SystemLog systemLog = new SystemLog();
            systemLog.setLogCode("SYS_" + System.currentTimeMillis());
            systemLog.setUserName("系统");
            systemLog.setOperation(operation);
            systemLog.setOperationTime(LocalDateTime.now());
            systemLog.setLogLevel(level);
            systemLog.setModule(module);
            systemLog.setIpAddress("127.0.0.1");
            
            if (exception != null) {
                systemLog.setRemark(remark + " - 错误信息: " + exception.getMessage());
            } else {
                systemLog.setRemark(remark);
            }
            
            systemLogMapper.insert(systemLog);
            log.debug("记录系统日志: 操作={}, 模块={}, 级别={}", operation, module, level);
        } catch (Exception e) {
            log.error("记录系统日志失败", e);
        }
    }

    /**
     * 记录错误日志
     */
    public void recordErrorLog(String operation, String module, String errorMessage, 
                              Exception exception, User user, HttpServletRequest request) {
        try {
            SystemLog systemLog = new SystemLog();
            systemLog.setLogCode("ERR_" + System.currentTimeMillis());
            
            if (user != null) {
                systemLog.setUserId(user.getUserId());
                systemLog.setUserName(user.getRealName());
            } else {
                systemLog.setUserName("系统");
            }
            
            systemLog.setOperation(operation);
            systemLog.setOperationTime(LocalDateTime.now());
            systemLog.setLogLevel("ERROR");
            systemLog.setModule(module);
            
            if (request != null) {
                systemLog.setIpAddress(getClientIpAddress(request));
            } else {
                systemLog.setIpAddress("127.0.0.1");
            }
            
            String remark = errorMessage;
            if (exception != null) {
                remark += " - 异常类型: " + exception.getClass().getSimpleName();
                remark += " - 异常信息: " + exception.getMessage();
            }
            systemLog.setRemark(remark);
            
            systemLogMapper.insert(systemLog);
            log.error("记录错误日志: 操作={}, 模块={}, 错误={}", operation, module, errorMessage);
        } catch (Exception e) {
            log.error("记录错误日志失败", e);
        }
    }

    /**
     * 记录警告日志
     */
    public void recordWarningLog(String operation, String module, String warningMessage, 
                                User user, HttpServletRequest request) {
        try {
            SystemLog systemLog = new SystemLog();
            systemLog.setLogCode("WARN_" + System.currentTimeMillis());
            
            if (user != null) {
                systemLog.setUserId(user.getUserId());
                systemLog.setUserName(user.getRealName());
            } else {
                systemLog.setUserName("系统");
            }
            
            systemLog.setOperation(operation);
            systemLog.setOperationTime(LocalDateTime.now());
            systemLog.setLogLevel("WARN");
            systemLog.setModule(module);
            systemLog.setRemark(warningMessage);
            
            if (request != null) {
                systemLog.setIpAddress(getClientIpAddress(request));
            } else {
                systemLog.setIpAddress("127.0.0.1");
            }
            
            systemLogMapper.insert(systemLog);
            log.warn("记录警告日志: 操作={}, 模块={}, 警告={}", operation, module, warningMessage);
        } catch (Exception e) {
            log.error("记录警告日志失败", e);
        }
    }

    /**
     * 获取系统日志列表（带分页和筛选）
     */
    public Page<SystemLog> getSystemLogList(int page, int size, String logLevel, 
                                           String module, String startDate, String endDate) {
        Page<SystemLog> pageInfo = new Page<>(page, size);
        QueryWrapper<SystemLog> queryWrapper = new QueryWrapper<>();
        
        // 添加筛选条件
        if (logLevel != null && !logLevel.trim().isEmpty()) {
            queryWrapper.eq("log_level", logLevel);
        }
        
        if (module != null && !module.trim().isEmpty()) {
            queryWrapper.eq("module", module);
        }
        
        if (startDate != null && !startDate.trim().isEmpty()) {
            queryWrapper.ge("operation_time", startDate + " 00:00:00");
        }
        
        if (endDate != null && !endDate.trim().isEmpty()) {
            queryWrapper.le("operation_time", endDate + " 23:59:59");
        }
        
        // 按时间倒序排列
        queryWrapper.orderByDesc("operation_time");
        
        return systemLogMapper.selectPage(pageInfo, queryWrapper);
    }

    /**
     * 删除指定ID的日志
     */
    public boolean deleteLogById(Integer logId) {
        try {
            int result = systemLogMapper.deleteById(logId);
            return result > 0;
        } catch (Exception e) {
            log.error("删除日志失败: logId={}", logId, e);
            return false;
        }
    }

    /**
     * 批量删除日志
     */
    public int batchDeleteLogs(List<Integer> logIds) {
        try {
            return systemLogMapper.deleteBatchIds(logIds);
        } catch (Exception e) {
            log.error("批量删除日志失败", e);
            return 0;
        }
    }

    /**
     * 按条件删除日志
     */
    public int deleteLogsByCondition(String startDate, String endDate, String logLevel, String module) {
        try {
            QueryWrapper<SystemLog> queryWrapper = new QueryWrapper<>();
            
            if (startDate != null && !startDate.trim().isEmpty()) {
                queryWrapper.ge("operation_time", startDate + " 00:00:00");
            }
            
            if (endDate != null && !endDate.trim().isEmpty()) {
                queryWrapper.le("operation_time", endDate + " 23:59:59");
            }
            
            if (logLevel != null && !logLevel.trim().isEmpty()) {
                queryWrapper.eq("log_level", logLevel);
            }
            
            if (module != null && !module.trim().isEmpty()) {
                queryWrapper.eq("module", module);
            }
            
            return systemLogMapper.delete(queryWrapper);
        } catch (Exception e) {
            log.error("按条件删除日志失败", e);
            return 0;
        }
    }

    /**
     * 清空所有日志
     */
    public int clearAllLogs() {
        try {
            QueryWrapper<SystemLog> queryWrapper = new QueryWrapper<>();
            return systemLogMapper.delete(queryWrapper);
        } catch (Exception e) {
            log.error("清空所有日志失败", e);
            return 0;
        }
    }

    /**
     * 获取日志统计信息
     */
    public SystemLogStatistics getLogStatistics() {
        try {
            QueryWrapper<SystemLog> queryWrapper = new QueryWrapper<>();
            
            // 总日志数
            Long totalCount = systemLogMapper.selectCount(queryWrapper);
            
            // 今日日志数
            String today = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            QueryWrapper<SystemLog> todayWrapper = new QueryWrapper<>();
            todayWrapper.ge("operation_time", today + " 00:00:00");
            todayWrapper.le("operation_time", today + " 23:59:59");
            Long todayCount = systemLogMapper.selectCount(todayWrapper);
            
            // 错误日志数
            QueryWrapper<SystemLog> errorWrapper = new QueryWrapper<>();
            errorWrapper.eq("log_level", "ERROR");
            Long errorCount = systemLogMapper.selectCount(errorWrapper);
            
            // 警告日志数
            QueryWrapper<SystemLog> warnWrapper = new QueryWrapper<>();
            warnWrapper.eq("log_level", "WARN");
            Long warnCount = systemLogMapper.selectCount(warnWrapper);
            
            return new SystemLogStatistics(totalCount, todayCount, errorCount, warnCount);
        } catch (Exception e) {
            log.error("获取日志统计信息失败", e);
            return new SystemLogStatistics(0L, 0L, 0L, 0L);
        }
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0].trim();
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        
        String remoteAddr = request.getRemoteAddr();
        return remoteAddr != null ? remoteAddr : "127.0.0.1";
    }

    /**
     * 日志统计信息内部类
     */
    public static class SystemLogStatistics {
        private Long totalCount;
        private Long todayCount;
        private Long errorCount;
        private Long warnCount;

        public SystemLogStatistics(Long totalCount, Long todayCount, Long errorCount, Long warnCount) {
            this.totalCount = totalCount;
            this.todayCount = todayCount;
            this.errorCount = errorCount;
            this.warnCount = warnCount;
        }

        // Getters and Setters
        public Long getTotalCount() { return totalCount; }
        public void setTotalCount(Long totalCount) { this.totalCount = totalCount; }
        
        public Long getTodayCount() { return todayCount; }
        public void setTodayCount(Long todayCount) { this.todayCount = todayCount; }
        
        public Long getErrorCount() { return errorCount; }
        public void setErrorCount(Long errorCount) { this.errorCount = errorCount; }
        
        public Long getWarnCount() { return warnCount; }
        public void setWarnCount(Long warnCount) { this.warnCount = warnCount; }
    }
}